import { ref, reactive, readonly, watch } from "vue";
import { defineStore, storeToRefs } from "pinia";
import { type messageType, store } from "../utils";
import $config from "@/config";
import { useLunchStoreHook } from "./lunch";
import { getAccessUserMessages } from "@/api/access";
import { setMessageRead, setMessageReadAll } from "@/api/message";

const { isWindowActive } = storeToRefs(useLunchStoreHook());

export const useMessageStore = defineStore("vas-message", () => {
  // 是否初始化
  const hasInit = ref(false);
  // 状态参数
  const state = reactive({
    // 请求体内容
    queryBody: null,
    // 是否请求中
    isQuery: false,
    // 是否暂存了消息请求
    isStoreQueryMsg: true
  });
  // 当前消息列表
  const currentMessage = ref<messageType["list"]>([]);
  // 当前未读总数
  const unreadMessage = ref(0);

  // ----- Functions -----

  // 请求并获取消息
  const handleQueryMsg = async () => {
    // 保证同一时间仅会请求一次
    if (state.isQuery) return;
    state.isQuery = true;
    if (!isWindowActive.value) {
      // 当前窗口未激活，忽略并记录本次更新
      state.isStoreQueryMsg = true;
      state.isQuery = false;
      return;
    }
    const res = await getAccessUserMessages();
    const total = res.data.totalUnread;
    if (hasInit.value && total > unreadMessage.value) {
      // 消息提示（首次进入时忽略）
      useLunchStoreHook().showWindowTips();
    }
    unreadMessage.value = total;
    currentMessage.value = res.data.list;
    hasInit.value = true;
    state.isQuery = false;
  };

  // 监听窗口激活状态
  watch(
    isWindowActive,
    async value => {
      // 当窗口激活时，执行一次请求（如果记录了暂存请求）
      if (value && state.isStoreQueryMsg) {
        state.isStoreQueryMsg = false;
        await handleQueryMsg();
      }
    },
    {
      immediate: true
    }
  );

  // ----- Actions -----

  /**
   * 轮询请求获取消息
   */
  const runQueryMsg = async () => {
    // 保证轮询的唯一性
    if (!state.queryBody) {
      state.queryBody = setInterval(
        async () => await handleQueryMsg(),
        $config.request.pollingInterval * 1000
      );
      await handleQueryMsg();
    }
  };

  /**
   * 设置单条消息已读状态
   *
   * @param id 消息ID
   * @param read 是否已读
   */
  const setMsgReadStatus = async (id: Id, read: boolean) => {
    const msg = currentMessage.value.find(item => item.id === id);
    if (msg) {
      if (read != msg.isRead) {
        unreadMessage.value += read ? -1 : 1;
      }
      if (unreadMessage.value < 0) unreadMessage.value = 0;
      msg.isRead = read;
      await setMessageRead(id, { read });
    }
  };

  /**
   * 设置全部消息为已读
   */
  const setMsgReadAll = async () => {
    currentMessage.value.forEach(msg => {
      msg.isRead = true;
    });
    unreadMessage.value = 0;
    await setMessageReadAll();
  };

  /**
   * 清除消息存储数据（通常退出登录调用）
   */
  const clearMsgStore = () => {
    unreadMessage.value = 0;
    currentMessage.value = [];
    if (!!state.queryBody) {
      clearInterval(state.queryBody);
      state.queryBody = null;
    }
    state.isQuery = false;
  };

  return {
    /** getter: 当前消息列表 */
    readMessageList: readonly(currentMessage),
    /** getter: 当前未读消息总数 */
    totalUnreadMessage: readonly(unreadMessage),
    /** getter: 轮询请求获取消息 */
    runQueryMsg,
    /** getter: 设置单条消息已读状态 */
    setMsgReadStatus,
    /** getter: 设置全部消息为已读 */
    setMsgReadAll,
    /** getter: 清除消息存储数据（通常退出登录调用） */
    clearMsgStore
  };
});

export function useMessageStoreHook() {
  return useMessageStore(store);
}
